import G6, {G6GraphEvent, Graph, INode, IPoint, IShape} from '@antv/g6';
import {G6Event, Item} from '@antv/g6-core/lib/types';
import React from 'react';
import NodeAttrField from '../consts/node-attr-field';
import GraphKeyName from '../consts/graph-key-name';

/**
 * 显示拖动时的阴影
 */
export default function () {
    G6.registerBehavior('custom:ghost-edge:display', {
        getDefaultCfg() {
            return {

            };
        },
        getEvents() {
            return {
                'custom:ghost-edge:display': 'handleGhostDisplay',
                'custom:ghost-edge:remove': 'handleGhostRemove',
            } as {
                [key in G6Event]?: string;
            };
        },
        handleGhostDisplay(event: React.DragEvent | G6GraphEvent) {
            const graph = this.graph as Graph;
            const {node, anchor} = graph.get(GraphKeyName.DRAG_EDGE_SOURCE) as {node: INode, anchor: IShape};
            const anchorIndex = anchor.attr(NodeAttrField.ANCHOR_ANCHOR_INDEX);

            graph.removeItem('ghost-edge');

            const sourceAnchor = (node.getAnchorPoints() as IPoint[]).find(item => item.anchorIndex === anchorIndex) as IPoint;
            const {x, y} = graph.getPointByClient(event.clientX, event.clientY);
            let endX = x;
            let endY = y;

            const deltaX = (x - sourceAnchor.x);
            const deltaY = (y - sourceAnchor.y);

            const absDeltaX = Math.abs(deltaX);
            const absDeltaY = Math.abs(deltaY);

            let rate = 1;
            if (absDeltaX > absDeltaY) {
                rate = 1 - 2 / absDeltaX;
            } else {
                rate = 1 - 2 / absDeltaY;
            }

            endX = sourceAnchor.x + deltaX * rate;
            endY = sourceAnchor.y + deltaY * rate;

            const edge = graph.addItem('edge', {
                id: 'ghost-edge',
                source: node.getModel().id,
                target: {x: endX, y: endY},
                sourceAnchor: anchorIndex,
                zIndex: 999999999
            }) as Item;
            edge.toFront();
            edge.setState('ghost', true);

        },
        handleGhostRemove(event: G6GraphEvent) {
            const graph = this.graph as Graph;
            graph.removeItem('ghost-edge');
        }
    });
}
